/*
 * @(#)VirtualClassFileObject.java 1.0 2009/12/01
 */
package stardust.core.java.compiler;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileObject;


/**
 * 虚拟类文件对象。
 * <p>
 * 用于支持 javax.tools 下的动态编译，在内存存储 Java 源程序。
 * <p/>
 * @version 1.0, 2009/12/01
 * @author ChenChang
 */
public class VirtualClassFileObject implements JavaFileObject
{

  /**
   * 全限定类名。
   */
  private String className;

  /**
   * 源程序。
   */
  private String source;

  /**
   * 源程序路径。
   */
  private URI uri;

  /**
   * 通过全限定类名和源程序创造一个虚拟类文件。
   * <p/>
   * @param className
* 全限定类名。
   * @param source
   * 源代码。
   */
  public VirtualClassFileObject(String className, String source)
  {
    this.className = className;
    this.source = source;

    try
    {
      this.uri = new URI(this.className.replaceAll("[.]", "/") + ".java");
    }
    catch(URISyntaxException e)
    {
      ;
    }
  }

  /**
   * 模拟删除虚拟文件。
   */
  public boolean delete()
  {
    return true;
  }

  /**
   * 获取源程序内容。
   */
  public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException
  {
    return this.source;
  }

  /**
   * 获取最后修改时间。
   */
  public long getLastModified()
  {
    return 0L;
  }

  /**
   * 获取类名。
   */
  public String getName()
  {
    return this.className;
  }

  /**
   * 获取资源的统一标识符。
   */
  public URI toUri()
  {
    return this.uri;
  }

  /**
   * 获取类的访问级别。
   */
  public Modifier getAccessLevel()
  {
    return Modifier.PUBLIC;
  }

  /**
   * 获取类种类。
   */
  public Kind getKind()
  {
    return Kind.SOURCE;
  }

  /**
   * 获取代码嵌套种类。
   */
  public NestingKind getNestingKind()
  {
    return NestingKind.TOP_LEVEL;
  }

  /**
   * 检查此文件对象是否与指定的简单名称和种类兼容。 简单名称是 Java Language Specification 3rd ed.，6.2
   * 节“名称和标识符”中定义的单个标识符（非限定）。
   */
  public boolean isNameCompatible(String simpleName, Kind kind)
  {
    String baseName = simpleName + kind.extension;

    return kind.equals(getKind())
           && (baseName.equals(toUri().getPath())
               || toUri().getPath().endsWith("/" + baseName));
  }

  /**
   * 检查比较全限定类名称的冲突。
   * <p/>
   * @param object
   * <p/>
   * @return
   */
  public boolean equals(VirtualClassFileObject object)
  {
    return object != null && object.getName().equals(this.className);
  }

  public String toString()
  {
    return this.source;
  }

  public InputStream openInputStream() throws IOException
  {
    throw new RuntimeException();
  }

  public OutputStream openOutputStream() throws IOException
  {
    throw new RuntimeException();
  }

  public Reader openReader(boolean ignoreEncodingErrors) throws IOException
  {
    throw new RuntimeException();
  }

  public Writer openWriter() throws IOException
  {
    throw new RuntimeException();
  }

}
